﻿using System;
using System.Diagnostics;
using System.Threading;

namespace NDK.Motion.MachineResources
{
    [Serializable]
    /// <summary>
    /// 单控气缸
    /// </summary>
  public  class SingleDriveCylinder : ICylinder
    {
        private string _name;
        private InputSetting _input_Home;
        private InputSetting _input_Work;
        private OutputSetting _output;

        /// <summary>
        /// 单控初始化函数
        /// </summary>
        /// <param name="name">自定义气缸名称</param>
        /// <param name="output">气缸的控制端口</param>
        /// <param name="input_Home">气缸的Home位的sensor，输入为null时不做检查</param>
        /// <param name="input_Work">气缸的Work位的sensor，输入为null时不做检查</param>
        /// <exception >output为空，抛出异常；input_Home和input_Work都为空时，抛出异常</exception>
        public SingleDriveCylinder(string name, OutputSetting output, InputSetting input_Home, InputSetting input_Work)
        {
            _name = name;
            _output = output;
            _input_Home = input_Home;
            _input_Work = input_Work;
            if (_input_Home == null && _input_Work == null)
            {
                throw new Exception("[" + _name + "] Work Sensor and Home sensor are null !");
            }
            if (_output == null)
            {
                throw new Exception("[" + _name + "] output is null !");
            }
        }
        public string Name
        {
            get
            {
                return _name;
            }

            set
            {
                _name = value;
            }
        }


        /// <summary>
        /// 气缸到Home位
        /// </summary>
        /// <returns>设置成功返回true</returns>
        public bool Home()
        {
            try
            {
                return _output.OFF();
            }
            catch (Exception ex)
            {
                throw new Exception("SingleDriveCylinder [" + _name + "] Home Exception:" + ex.StackTrace);
            }
        }
        /// <summary>
        /// 等待气缸到Home位，
        /// 超时返回true
        /// </summary>
        /// <param name="timeout">超时时间</param>
        /// <returns>true：超时，false：正常</returns>
        public bool WaitHome(int timeout = int.MaxValue)
        {
            Stopwatch sw = new Stopwatch();
            sw.Restart();
            bool isTimeout = false;

            try
            {
                if (_input_Home != null)
                {
                    while (_input_Home.GetStatus() == false)
                    {
                        if (sw.ElapsedMilliseconds >= timeout)
                        {
                            return true;
                        }
                        Thread.Sleep(1);
                    }
                }
                if (_input_Work != null)
                {
                    while (_input_Work.GetStatus() == true)
                    {
                        if (sw.ElapsedMilliseconds >= timeout)
                        {
                            return true;
                        }
                        Thread.Sleep(1);
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception("SingleDriveCylinder [" + _name + "] WaitHome Exception!" + ex.StackTrace);
            }
            return isTimeout;
        }

        /// <summary>
        /// 气缸到Work位
        /// </summary>
        /// <returns>设置成功，返回true</returns>
        public bool Work()
        {
            try
            {
                return _output.ON();
            }
            catch (Exception ex)
            {
                throw new Exception("SingleDriveCylinder [" + _name + "] Work Exception:" + ex.StackTrace);
            }
        }
        /// <summary>
        /// 等待气缸到Work位，
        /// 超时返回true
        /// </summary>
        /// <param name="timeout">超时时间</param>
        /// <returns>true：超时，false：正常</returns>
        public bool WaitWork(int timeout = int.MaxValue)
        {
            Stopwatch sw = new Stopwatch();
            sw.Restart();
            bool isTimeout = false;

            try
            {
                if (_input_Home != null)
                {
                    while (_input_Home.GetStatus() == true)
                    {
                        if (sw.ElapsedMilliseconds >= timeout)
                        {
                            return true;
                        }
                        Thread.Sleep(1);
                    }
                }
                if (_input_Work != null)
                {
                    while (_input_Work.GetStatus() == false)
                    {
                        if (sw.ElapsedMilliseconds >= timeout)
                        {
                            return true;
                        }
                        Thread.Sleep(1);
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception("SingleDriveCylinder [" + _name + "] WaitWork Exception!" + ex.StackTrace);
            }
            return isTimeout;
        }
        /// <summary>
        /// 气缸到Work位，并且等待其到达Work位
        /// </summary>
        /// <param name="timeout">超时时间</param>
        /// <returns></returns>
        public bool WorkAndWaitDone(int timeout = int.MaxValue)
        {
            bool isTimeout = false;
            try
            {
                Work();
                isTimeout = WaitWork(timeout);
            }
            catch (Exception ex)
            {
                throw new Exception("[" + _name + "] WorkAndWaitDone Exception:" + ex.StackTrace);
            }
            return isTimeout;
        }
        /// <summary>
        /// 气缸到Home位，并且等待其到达Home位
        /// </summary>
        /// <param name="timeout">超时时间</param>
        /// <returns></returns>
        public bool HomeAndWaitDone(int timeout = int.MaxValue)
        {
            bool isTimeout = false;
            try
            {
                Home();
                isTimeout = WaitHome(timeout);
            }
            catch (Exception ex)
            {
                throw new Exception("[" + _name + "] HomeAndWaitDone Exception:" + ex.StackTrace);
            }
            return isTimeout;
        }

        /// <summary>
        /// 检查是否在Home点
        /// </summary>
        /// <returns></returns>
        public bool? isHomed()
        {
            return _input_Home?.GetStatus();
        }

        /// <summary>
        /// 检查是否在Work点
        /// </summary>
        /// <returns></returns>
        public bool? isWorked()
        {
            return _input_Work?.GetStatus();
        }

        /// <summary>
        /// 单控气缸不支持，返回null
        /// </summary>
        /// <returns></returns>
        public bool? Stop()
        {
            return null;
        }
    }
}
